﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using PasteLoggerBoard.Controllers;
using PasteLoggerBoard.HttpApi.Host.handler;
using PasteLoggerBoard.redismodel;
using PasteLoggerBoard.reportmodels;
using Volo.Abp.Application.Dtos;

namespace PasteLoggerBoard.HttpApi.Host.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    [ApiController]
    [Route("/api/app/[controller]/[action]")]
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
    public class ReportController : IBaseController
    {

        private IAppCache _cache => LazyServiceProvider.LazyGetRequiredService<IAppCache>();
        //private ModelHelper _modelHelper => LazyServiceProvider.LazyGetRequiredService<ModelHelper>();
        private CollectHandler _collectHandler => LazyServiceProvider.LazyGetRequiredService<CollectHandler>();


        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbContext"></param>
        public ReportController(IPasteLoggerBoardDbContext dbContext) : base(dbContext)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<ReportLevel>> Level(InputReport input)
        {
            //这里验证权限等！

            var datas = await _collectHandler.ReportLevel(_dbContext, input.sdate, input.edate, input.appname);
            if (input.edate.Subtract(input.sdate).TotalDays < 2)
            {
                if (input.edate > DateTime.Now)
                {
                    var hits = await _collectHandler.CollectLevelHour(null, DateTime.Now, _cache);
                    if (hits != null && hits.Count > 0)
                    {
                        if (datas == null)
                        {
                            datas = new List<ReportLevel>();
                        }
                        var _currhour = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:00:00"));
                        var das = hits.Where(x => x.AppName == input.appname).GroupBy(x => new { status = x.LogLevel, date = x.DataDate })
                            .Select(x => new ReportLevel
                            {
                                DataDate = x.Key.date,
                                HitTime = x.Sum(y => y.HitTime),
                                LogLevel = x.Key.status
                            }).ToList();
                        if (das != null && das.Count > 0)
                        {
                            datas.AddRange(das);
                        }
                    }
                }
            }
            return datas;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<ReportStatus>> Status(InputReport input)
        {
            //这里验证权限等！

            var datas = await _collectHandler.ReportStatus(_dbContext, input.sdate, input.edate, input.appname);

            if (input.edate.Subtract(input.sdate).TotalDays < 2)
            {
                if (input.edate > DateTime.Now)
                {
                    var hits = await _collectHandler.CollectStatusHour(null, DateTime.Now, _cache);
                    if (hits != null && hits.Count > 0)
                    {
                        if (datas == null)
                        {
                            datas = new List<ReportStatus>();
                        }
                        var _currhour = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:00:00"));
                        var das = hits.Where(x => x.AppName == input.appname).GroupBy(x => new { status = x.StatusCode, date = x.DataDate })
                            .Select(x => new ReportStatus
                            {
                                DataDate = x.Key.date,
                                HitTime = x.Sum(y => y.HitTime),
                                StatusCode = x.Key.status
                            }).ToList();
                        if (das != null && das.Count > 0)
                        {
                            datas.AddRange(das);
                        }
                    }
                }
            }

            return datas;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<ReportPath>> Path(InputReport input)
        {
            //这里验证权限等！

            var datas = await _collectHandler.ReportPath(_dbContext, input.sdate, input.edate, input.appname);

            return datas;
        }

        /// <summary>
        /// 按照分页获取路径访问信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PagedResultDto<ReportPath>> RankPath(InputReport input)
        {
            var datas = await _collectHandler.ReportSumPath(_dbContext, input.sdate, input.edate, input.appname, input.page, input.size);
            return datas;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<ReportClientIp>> ClientIp(InputReport input)
        {
            //这里验证权限等！
            var datas = await _collectHandler.ReportClientIp(_dbContext, input.sdate, input.edate, input.appname);
            return datas;
        }

        /// <summary>
        /// 按照分页获取客户端IP记录信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PagedResultDto<ReportClientIp>> RankClientIp(InputReport input)
        {
            var datas = await _collectHandler.ReportSumClientIp(_dbContext, input.sdate, input.edate, input.appname, input.page, input.size);
            return datas;
        }

        /// <summary>
        /// 统计IP的小时数据
        /// </summary>
        /// <param name="sdate"></param>
        /// <returns></returns>
        /// <exception cref="PasteLoggerBoardException"></exception>
        [HttpGet]
        public async Task<string> CollectHourClientIp(DateTime sdate)
        {
            long.TryParse(DateTime.Now.ToString("yyyyMMddHH"),out var _now);
            long.TryParse(sdate.ToString("yyyyMMddHH"),out var _date);
            if (_date >= _now)
            {
                throw new PasteLoggerBoardException("日期错误，请选择之前的时间，至少是上一个小时！");
            }
             await _collectHandler.CollectClientIpHour(_dbContext,sdate,_cache);
            return "提交成功";
        }

    }

    /// <summary>
    /// 
    /// </summary>
    public class InputReport
    {
        /// <summary>
        /// 
        /// </summary>
        [MaxLength(16)]
        [Required(ErrorMessage = "应用名称必填！")]
        public string appname { get; set; } = "";

        /// <summary>
        /// 
        /// </summary>
        public DateTime sdate { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public DateTime edate { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public int page { get; set; } = 1;

        /// <summary>
        /// 
        /// </summary>
        public int size { get; set; } = 100;
    }

}
